package cc.shacocloud.mirage.restful;

import cc.shacocloud.mirage.restful.util.PathUtil;
import cc.shacocloud.mirage.utils.PathMatcher;
import cc.shacocloud.mirage.utils.collection.CollUtil;
import cc.shacocloud.mirage.utils.collection.SelfSortSet;
import cc.shacocloud.mirage.utils.comparator.AnnotationOrderComparator;
import lombok.Setter;
import org.jetbrains.annotations.NotNull;

import java.util.Collections;
import java.util.List;

/**
 * 拦截处理器聚合对象，通 {@link #match} 方法匹配合适的拦截器集合，然后委派给 {@link HandlerInterceptor} 处理
 */
public class HandlerInterceptorComposite {
    
    private final List<InterceptorMappingInfo> interceptorMappings = new SelfSortSet<>(
            InterceptorMappingInfo::getOrder, InterceptorMappingInfo::getInterceptorName);
    
    /**
     * 路径匹配器
     */
    @Setter
    private PathMatcher pathMatcher = PathUtil.DEFAULT_PATH_MATCHER;
    
    /**
     * 返回与指定路径相匹配的拦截器集合，拦截器集合使用 {@link AnnotationOrderComparator#INSTANCE} 排序
     *
     * @param paths 带匹配的路径
     * @return 匹配的拦截器集合
     */
    @NotNull
    public List<HandlerInterceptor> match(String... paths) {
        List<HandlerInterceptor> interceptors = PathUtil.match(this.interceptorMappings, this.pathMatcher, paths);
        if (CollUtil.isEmpty(interceptors)) return Collections.emptyList();
        
        interceptors.sort(AnnotationOrderComparator.INSTANCE);
        return interceptors;
    }
    
    
    /**
     * 添加拦截器映射
     *
     * @param interceptorMappingInfo 拦截器映射信息
     */
    public void addInterceptor(InterceptorMappingInfo interceptorMappingInfo) {
        this.interceptorMappings.add(interceptorMappingInfo);
    }
    
    /**
     * 添加拦截器映射
     *
     * @param interceptorMappingInfos 拦截器映射信息
     */
    public void addInterceptor(List<InterceptorMappingInfo> interceptorMappingInfos) {
        this.interceptorMappings.addAll(interceptorMappingInfos);
    }
    
    /**
     * 获取注册的拦截器映射
     */
    public List<InterceptorMappingInfo> getInterceptorMappings() {
        if (CollUtil.isEmpty(interceptorMappings)) {
            return Collections.emptyList();
        }
        return Collections.unmodifiableList(interceptorMappings);
    }
}
